package com.example.skytakeoutserver.repository

import com.example.skytakeoutserver.data.entity.Dish
import org.springframework.data.r2dbc.repository.Modifying
import org.springframework.data.r2dbc.repository.Query
import org.springframework.data.repository.query.Param
import org.springframework.data.repository.reactive.ReactiveCrudRepository
import org.springframework.stereotype.Repository
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono
import java.time.Instant


/**
 * 区别于JPA
 */
@Repository
interface DishRepository
    : ReactiveCrudRepository<Dish, Long> {
    /**
     * 根据条件查询Dish
     *
     * select * from Dish d where
     * name is null or d.name like <xxx>
     * and status is null or d.status = <yyy>
     * and categoryId is null or d.categoryId = <zzz>
     */
    @Query("select d from Dish d where (:name is null or d.name like %:name%) and (:status is null or d.status = :status) and (:categoryId is null or d.categoryId = :categoryId)")
    fun findDishesByOptionalCondition(
        @Param("name")
        name: String?,
        @Param("status")
        type: Int?,
        @Param("categoryId")
        categoryId: Long?,
    ): Flux<Dish>

    /**
     * 更新Dish状态
     *
     * update dish set
     * status = <xxx> ,
     * update_time = <yyy> ,
     * update_user = <zzz> ,
     * where id = <id>
     */
    @Modifying
    @Query("UPDATE dish SET status = :status WHERE id = :id")
    fun updateStatusById(
        id: Long,
        status: Int,
        updateTime: Instant,
        updateUser: Long
    ): Mono<Long>


    /**
     *
     */
    fun findDishByCategoryId(categoryId: Long): Flux<Dish>

    /**
     *
     */
    fun findByIdIn(ids: List<Long>): Mono<Dish>

}

